#include "AnaDef.h"
#include "XGLUtils.h"
#include "StringArray.h"

#define EPSILON 1e-12

void DrawList(TList *list)
{
  const Int_t col[] = {kGreen, kRed, kBlue, kMagenta, kBlack, kRed, kMagenta, kBlue};
  const Int_t sty[] = {22, 23, 20, 21, 29, 28, 25, 30};
  const Int_t nc = sizeof(col)/sizeof(Int_t);

  const Int_t nn = list->GetEntries();
  if(nn>nc){
    printf("DrawList not enough color nc %d nn %d\n", nc, nn);exit(1);
  }

  TCanvas *c1 = new TCanvas;
  gPad->SetLogx();
  TLegend *lg=new TLegend(0.5, 0.5, 0.9, 0.9);

  Double_t gmax = -1e10;
  for(Int_t ii=0; ii<nn; ii++){
    TGraph * gr = (TGraph*) list->At(ii);
    gr->SetMarkerStyle(sty[ii]);
    gr->SetMarkerColor(col[ii]);
    if(gr->GetMaximum()>gmax)
      gmax=gr->GetMaximum();
  }

  for(Int_t ii=0; ii<nn; ii++){
    TGraph * gr = (TGraph*) list->At(ii);
    gr->GetYaxis()->SetRangeUser(0, gmax*1.5);
    gr->GetXaxis()->SetLimits(pow(10,-0.5), pow(10, 4.5));
    gr->Draw(ii?"pl":"apl");

    lg->AddEntry(gr, gr->GetName(), "p");
  }
  lg->SetFillStyle(-1);
  lg->Draw();
  c1->Print(Form("%s.png",list->GetName()));
}

void NewSummary(TString tnames, TList *list,  Char_t *sy, Char_t *sey, const Double_t x1=-999, const Double_t x0 = -999, const Double_t x2 = -999)
{
  list->SetName(sy);

  StringArray sa(tnames);    
  while(sa.Length()){
    const TString treename = sa.PopFront();
    cout<<treename<<endl;

    //(Char_t*) "x" for "deprecated conversion from string constant to 'Char_t*'"    
    //p=x for cosmic
    //kTRUE for kXLogToLinear
    //"ntot>500 && x>-0.25 && ( abs(p-x)>1e-6 || ( abs(p-x)<1e-6 && x<4 ))"
    //too large x does not have x-error calculated!
    TGraphAsymmErrors *gr = XGLUtils::TreeToGraph(treename, "ntot>1550 && x>-0.25", (Char_t*) "x", sy, (Char_t*) "ex0", (Char_t*) "ex1", sey, kTRUE);

    gr->GetXaxis()->SetTitle("x");
    gr->GetYaxis()->SetTitle(sy);

    const Int_t np = gr->GetN();
    
    if(x1>-990){
      const Double_t *xtmp = gr->GetX();
      const Double_t *ytmp = gr->GetY();
      
      Int_t sortx[np];
      TMath::Sort(np, xtmp, sortx, kFALSE);
      Double_t xs[np], ys[np];
      for(Int_t ii=0; ii<np; ii++){
        xs[ii]=log10(xtmp[sortx[ii]]);//use log10() for interpolation
        ys[ii]=ytmp[sortx[ii]];
      }

      Int_t i0 = -1, ni=-1;
      for(Int_t jj=0; jj<np; jj++){
        if(xs[jj]>x0 && i0<0){
          i0=jj;
        }
        if(xs[jj]>x2 && ni<0){
          ni = jj-i0;
        }
      }
      if(i0<0 || ni<0){
        printf("NewSummary x0 x2 not covered!! %f %f %d %d\n", x0, x2, i0, ni);exit(1);
      }

      Double_t y1 = -999, dum;
      XGLUtils::Polint(ni, &(xs[i0]), &(ys[i0]), x1, y1, dum);
      printf("NewSummary %s %s x0 %e , x1 %e , x2 %e -- i0 %d , ni %d -- y1 %e\n", treename.Data(), sy, x0, x1, x2, i0, ni, y1);

      if(y1<EPSILON){
        printf("NewSummary y1 < eps! %e %e \n", y1, EPSILON);exit(1);
      }
      XGLUtils::ScaleGraph(gr, 1/y1*1.25);
    }

    const Double_t *ytmp = gr->GetY();
    Int_t sorty[np];
    TMath::Sort(np, ytmp, sorty, kTRUE);//true = down
    gr->SetMaximum(ytmp[sorty[0]]);

    list->Add(gr);
  }
}

int main(int argc, char * argv[])
{
  for(int ii=0; ii<argc; ii++){
    printf("%d: %s\n", ii, argv[ii]);
  }

  if(argc!=3){
    printf("argc!=3!!\n"); return 1;
  }

  TFile::Open(argv[1]);

  TList * fl_ntot       = new TList; NewSummary(argv[2], fl_ntot,       (Char_t *)"ntot",       (Char_t *)"");                              DrawList(fl_ntot);
  TList * fl_chi2dof    = new TList; NewSummary(argv[2], fl_chi2dof,    (Char_t *)"chi2dof",    (Char_t *)"");                              DrawList(fl_chi2dof);

  TList * fl_mpv        = new TList; NewSummary(argv[2], fl_mpv,        (Char_t *)"mpv",        (Char_t *)"empv",       log10(25), 0.7, 1.9); DrawList(fl_mpv);

  TList * fl_a     = new TList; NewSummary(argv[2], fl_a,     (Char_t *)"a",     (Char_t *)"ea");                        DrawList(fl_a);
  TList * fl_delta = new TList; NewSummary(argv[2], fl_delta, (Char_t *)"delta", (Char_t *)"edelta", log10(25), 0.7, 1.9); DrawList(fl_delta);
  TList * fl_xi    = new TList; NewSummary(argv[2], fl_xi,    (Char_t *)"xi",    (Char_t *)"exi");                       DrawList(fl_xi);
  TList * fl_sigma = new TList; NewSummary(argv[2], fl_sigma, (Char_t *)"sigma", (Char_t *)"esigma");                    DrawList(fl_sigma);
  TList * fl_kappa = new TList; NewSummary(argv[2], fl_kappa, (Char_t *)"kappa", (Char_t *)"ekappa");                    DrawList(fl_kappa);

  TList *fl = 0x0;  
  TFile *fout=new TFile("list.root","recreate");
  fl = fl_ntot;       fl->Write(fl->GetName(), TList::kSingleKey);
  fl = fl_chi2dof;    fl->Write(fl->GetName(), TList::kSingleKey);
  fl = fl_mpv;        fl->Write(fl->GetName(), TList::kSingleKey);
  fl = fl_a;     fl->Write(fl->GetName(), TList::kSingleKey);
  fl = fl_delta; fl->Write(fl->GetName(), TList::kSingleKey);
  fl = fl_xi;    fl->Write(fl->GetName(), TList::kSingleKey);
  fl = fl_sigma; fl->Write(fl->GetName(), TList::kSingleKey);
  fl = fl_kappa; fl->Write(fl->GetName(), TList::kSingleKey);

  fout->Save();
  fout->Close();

  return 0;
}
